import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:path/path.dart' as p;

// 使用统一入口的目录选择器（Web 使用 File System Access，其他平台使用 file_picker）
import 'package:ideology/platform/directory_picker.dart' as dir_picker;

/// 抽象的文件服务接口。
///
/// 负责提供与平台无关的常用文件操作能力：
/// - 目录选择（跨平台统一入口）；
/// - 文本读取；
/// - 路径拼接与提取；
/// - 目录存在性检查；
/// - 目录实体构造；
/// - 项目关闭时的资源清理。
abstract class FileService {
  /// 选择文件夹，返回“路径/显示名”或 `null`。
  ///
  /// - 桌面/Android 等平台：返回真实的绝对路径；
  /// - Web（Chromium）平台：返回形如 `fs://{目录名}` 的**显示名**。
  ///   > Web 上真实读写需依赖浏览器句柄；本方法仅返回可显示/记录的标识。
  Future<String?> pickDirectory();

  /// 按路径读取整个文本文件内容。
  Future<String> readAsString(String path);

  /// 拼接路径片段。
  ///
  /// 等价于 `p.joinAll`，支持最多四个片段的便捷写法。
  String join(String a, [String? b, String? c, String? d]);

  /// 获取路径的基本名（去除目录前缀）。
  String basename(String path);

  /// 检查指定目录是否存在。
  Future<bool> dirExists(String path);

  /// 根据路径返回一个 [Directory] 实例（不进行存在性检查）。
  Directory directory(String path);

  /// 关闭当前项目的资源，执行必要的清理操作。
  ///
  /// 该方法用于在上层“关闭项目”时做收尾（如清缓存、关闭文件流等）。
  void closeProject();
}

/// 默认实现的文件服务。
///
/// - 目录选择通过 `directory_picker` 的统一入口实现跨平台；
/// - 本地文件读取使用 `dart:io`；
/// - 路径处理依赖 `package:path`。
class DefaultFileService implements FileService {
  @override
  Future<String?> pickDirectory() async {
    try {
      final picked = await dir_picker.pickDirectory();
      // 统一返回可显示的“路径/名称”（Web 为 fs://name）
      return picked?.displayPath;
    } catch (e) {
      if (kDebugMode) {
        // 调试模式下输出错误信息，避免在发布环境污染日志
        // ignore: avoid_print
        print('pickDirectory error: $e');
      }
      return null;
    }
  }

  @override
  Future<String> readAsString(String path) => File(path).readAsString();

  @override
  String join(String a, [String? b, String? c, String? d]) =>
      p.joinAll([a, if (b != null) b, if (c != null) c, if (d != null) d]);

  @override
  String basename(String path) => p.basename(path);

  @override
  Future<bool> dirExists(String path) => Directory(path).exists();

  @override
  Directory directory(String path) => Directory(path);

  @override
  void closeProject() {
    // 预留：关闭项目的清理逻辑（清缓存、关闭流/句柄等）
    if (kDebugMode) {
      // ignore: avoid_print
      print('Project closed');
    }
  }
}
